home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / ext2 / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  14.3 KB  |  498 lines

  1. /*
  2.  *  linux/fs/ext2/inode.c
  3.  *
  4.  *  Copyright (C) 1992, 1993  Remy Card (card@masi.ibp.fr)
  5.  *
  6.  *  from
  7.  *
  8.  *  linux/fs/minix/inode.c
  9.  *
  10.  *  Copyright (C) 1991, 1992  Linus Torvalds
  11.  *
  12.  *  Goal-directed block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
  13.  */
  14.  
  15. #include <asm/segment.h>
  16. #include <asm/system.h>
  17.  
  18. #include <linux/errno.h>
  19. #include <linux/fs.h>
  20. #include <linux/ext2_fs.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/stat.h>
  24. #include <linux/string.h>
  25. #include <linux/locks.h>
  26.  
  27. void ext2_put_inode (struct inode * inode)
  28. {
  29.     if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
  30.         inode->i_ino == EXT2_ACL_DATA_INO)
  31.         return;
  32.     inode->i_size = 0;
  33.     if (inode->i_blocks)
  34.         ext2_truncate (inode);
  35.     ext2_free_inode (inode);
  36. }
  37.  
  38. #define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
  39.  
  40. static int block_bmap (struct buffer_head * bh, int nr)
  41. {
  42.     int tmp;
  43.  
  44.     if (!bh)
  45.         return 0;
  46.     tmp = ((unsigned long *) bh->b_data)[nr];
  47.     brelse (bh);
  48.     return tmp;
  49. }
  50.  
  51. int ext2_bmap (struct inode * inode, int block)
  52. {
  53.     int i;
  54.     int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
  55.  
  56.     if (block < 0) {
  57.         ext2_warning (inode->i_sb, "ext2_bmap", "block < 0");
  58.         return 0;
  59.     }
  60.     if (block >= EXT2_NDIR_BLOCKS + addr_per_block +
  61.              addr_per_block * addr_per_block +
  62.              addr_per_block * addr_per_block * addr_per_block) {
  63.         ext2_warning (inode->i_sb, "ext2_bmap", "block > big");
  64.         return 0;
  65.     }
  66.     if (block < EXT2_NDIR_BLOCKS)
  67.         return inode_bmap (inode, block);
  68.     block -= EXT2_NDIR_BLOCKS;
  69.     if (block < addr_per_block) {
  70.         i = inode_bmap (inode, EXT2_IND_BLOCK);
  71.         if (!i)
  72.             return 0;
  73.         return block_bmap (bread (inode->i_dev, i,
  74.                       inode->i_sb->s_blocksize), block);
  75.     }
  76.     block -= addr_per_block;
  77.     if (block < addr_per_block * addr_per_block) {
  78.         i = inode_bmap (inode, EXT2_DIND_BLOCK);
  79.         if (!i)
  80.             return 0;
  81.         i = block_bmap (bread (inode->i_dev, i,
  82.                        inode->i_sb->s_blocksize),
  83.                 block / addr_per_block);
  84.         if (!i)
  85.             return 0;
  86.         return block_bmap (bread (inode->i_dev, i,
  87.                       inode->i_sb->s_blocksize),
  88.                    block & (addr_per_block - 1));
  89.     }
  90.     block -= addr_per_block * addr_per_block;
  91.     i = inode_bmap (inode, EXT2_TIND_BLOCK);
  92.     if (!i)
  93.         return 0;
  94.     i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
  95.             block / (addr_per_block * addr_per_block));
  96.     if (!i)
  97.         return 0;
  98.     i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
  99.             (block / addr_per_block) & (addr_per_block - 1));
  100.     if (!i)
  101.         return 0;
  102.     return block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
  103.                block & (addr_per_block - 1));
  104. }
  105.  
  106. static struct buffer_head * inode_getblk (struct inode * inode, int nr,
  107.                       int create, int new_block, int * err)
  108. {
  109.     int tmp, goal = 0;
  110.     unsigned long * p;
  111.     struct buffer_head * result;
  112.     int blocks = inode->i_sb->s_blocksize / 512;
  113.  
  114.     p = inode->u.ext2_i.i_data + nr;
  115. repeat:
  116.     tmp = *p;
  117.     if (tmp) {
  118.         result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
  119.         if (tmp == *p)
  120.             return result;
  121.         brelse (result);
  122.         goto repeat;
  123.     }
  124.     if (!create || new_block >= 
  125.         (current->rlim[RLIMIT_FSIZE].rlim_cur >>
  126.          EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
  127.         *err = -EFBIG;
  128.         return NULL;
  129.     }
  130.     if (inode->u.ext2_i.i_next_alloc_block == new_block)
  131.         goal = inode->u.ext2_i.i_next_alloc_goal;
  132.  
  133.     ext2_debug ("hint = %d,", goal);
  134.  
  135.     if (!goal) {
  136.         for (tmp = nr - 1; tmp >= 0; tmp--) {
  137.             if (inode->u.ext2_i.i_data[tmp]) {
  138.                 goal = inode->u.ext2_i.i_data[tmp];
  139.                 break;
  140.             }
  141.         }
  142.         if (!goal)
  143.             goal = (inode->u.ext2_i.i_block_group * 
  144.                 EXT2_BLOCKS_PER_GROUP(inode->i_sb)) +
  145.                    inode->i_sb->u.ext2_sb.s_es->s_first_data_block;
  146.     }
  147.  
  148.     ext2_debug ("goal = %d.\n", goal);
  149.  
  150.     tmp = ext2_new_block (inode->i_sb, goal);
  151.     if (!tmp)
  152.         return NULL;
  153.     result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
  154.     if (*p) {
  155.         ext2_free_block (inode->i_sb, tmp);
  156.         brelse (result);
  157.         goto repeat;
  158.     }
  159.     *p = tmp;
  160.     inode->u.ext2_i.i_next_alloc_block = new_block;
  161.     inode->u.ext2_i.i_next_alloc_goal = tmp;
  162.     inode->i_ctime = CURRENT_TIME;
  163.     inode->i_blocks += blocks;
  164.     if (IS_SYNC(inode))
  165.         ext2_sync_inode (inode);
  166.     else
  167.         inode->i_dirt = 1;
  168.     return result;
  169. }
  170.  
  171. static struct buffer_head * block_getblk (struct inode * inode,
  172.                       struct buffer_head * bh, int nr,
  173.                       int create, int blocksize, 
  174.                       int new_block, int * err)
  175. {
  176.     int tmp, goal = 0;
  177.     unsigned long * p;
  178.     struct buffer_head * result;
  179.     int blocks = inode->i_sb->s_blocksize / 512;
  180.  
  181.     if (!bh)
  182.         return NULL;
  183.     if (!bh->b_uptodate) {
  184.         ll_rw_block (READ, 1, &bh);
  185.         wait_on_buffer (bh);
  186.         if (!bh->b_uptodate) {
  187.             brelse (bh);
  188.             return NULL;
  189.         }
  190.     }
  191.     p = (unsigned long *) bh->b_data + nr;
  192. repeat:
  193.     tmp = *p;
  194.     if (tmp) {
  195.         result = getblk (bh->b_dev, tmp, blocksize);
  196.         if (tmp == *p) {
  197.             brelse (bh);
  198.             return result;
  199.         }
  200.         brelse (result);
  201.         goto repeat;
  202.     }
  203.     if (!create || new_block >= 
  204.         (current->rlim[RLIMIT_FSIZE].rlim_cur >> 
  205.          EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
  206.         brelse (bh);
  207.         *err = -EFBIG;
  208.         return NULL;
  209.     }
  210.     if (inode->u.ext2_i.i_next_alloc_block == new_block)
  211.         goal = inode->u.ext2_i.i_next_alloc_goal;
  212.     if (!goal) {
  213.         for (tmp = nr - 1; tmp >= 0; tmp--) {
  214.             if (((unsigned long *) bh->b_data)[tmp]) {
  215.                 goal = ((unsigned long *)bh->b_data)[tmp];
  216.                 break;
  217.             }
  218.         }
  219.         if (!goal)
  220.             goal = bh->b_blocknr + 1;
  221.     }
  222.     tmp = ext2_new_block (inode->i_sb, goal);
  223.     if (!tmp) {
  224.         brelse (bh);
  225.         return NULL;
  226.     }
  227.     result = getblk (bh->b_dev, tmp, blocksize);
  228.     if (*p) {
  229.         ext2_free_block (inode->i_sb, tmp);
  230.         brelse (result);
  231.         goto repeat;
  232.     }
  233.     *p = tmp;
  234.     bh->b_dirt = 1;
  235.     if (IS_SYNC(inode)) {
  236.         ll_rw_block (WRITE, 1, &bh);
  237.         wait_on_buffer (bh);
  238.     }
  239.     inode->i_ctime = CURRENT_TIME;
  240.     inode->i_blocks += blocks;
  241.     inode->i_dirt = 1;
  242.     inode->u.ext2_i.i_next_alloc_block = new_block;
  243.     inode->u.ext2_i.i_next_alloc_goal = tmp;
  244.     brelse (bh);
  245.     return result;
  246. }
  247.  
  248. struct buffer_head * ext2_getblk (struct inode * inode, long block,
  249.                   int create, int * err)
  250. {
  251.     struct buffer_head * bh;
  252.     unsigned long b;
  253.     unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
  254.  
  255.     *err = -EIO;
  256.     if (block < 0) {
  257.         ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
  258.         return NULL;
  259.     }
  260.     if (block > EXT2_NDIR_BLOCKS + addr_per_block  +
  261.             addr_per_block * addr_per_block +
  262.             addr_per_block * addr_per_block * addr_per_block) {
  263.         ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
  264.         return NULL;
  265.     }
  266.     /* If this is a sequential block allocation, set the next_alloc_block
  267.        to this block now so that all the indblock and data block
  268.        allocations use the same goal zone */
  269.  
  270.     ext2_debug ("block %lu, next %lu, goal %lu.\n", block, 
  271.             inode->u.ext2_i.i_next_alloc_block,
  272.             inode->u.ext2_i.i_next_alloc_goal);
  273.  
  274.     if (block == inode->u.ext2_i.i_next_alloc_block + 1) {
  275.         inode->u.ext2_i.i_next_alloc_block++;
  276.         inode->u.ext2_i.i_next_alloc_goal++;
  277.     }
  278.  
  279.     *err = -ENOSPC;
  280.     b = block;
  281.     if (block < EXT2_NDIR_BLOCKS)
  282.         return inode_getblk (inode, block, create, b, err);
  283.     block -= EXT2_NDIR_BLOCKS;
  284.     if (block < addr_per_block) {
  285.         bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, err);
  286.         return block_getblk (inode, bh, block, create,
  287.                      inode->i_sb->s_blocksize, b, err);
  288.     }
  289.     block -= addr_per_block;
  290.     if (block < addr_per_block * addr_per_block) {
  291.         bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, err);
  292.         bh = block_getblk (inode, bh, block / addr_per_block, create,
  293.                    inode->i_sb->s_blocksize, b, err);
  294.         return block_getblk (inode, bh, block & (addr_per_block - 1),
  295.                      create, inode->i_sb->s_blocksize, b, err);
  296.     }
  297.     block -= addr_per_block * addr_per_block;
  298.     bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, err);
  299.     bh = block_getblk (inode, bh, block/(addr_per_block * addr_per_block),
  300.                create, inode->i_sb->s_blocksize, b, err);
  301.     bh = block_getblk (inode, bh, (block/addr_per_block) & (addr_per_block - 1),
  302.                create, inode->i_sb->s_blocksize, b, err);
  303.     return block_getblk (inode, bh, block & (addr_per_block - 1), create,
  304.                  inode->i_sb->s_blocksize, b, err);
  305. }
  306.  
  307. struct buffer_head * ext2_bread (struct inode * inode, int block, 
  308.                  int create, int *err)
  309. {
  310.     struct buffer_head * bh;
  311.  
  312.     bh = ext2_getblk (inode, block, create, err);
  313.     if (!bh || bh->b_uptodate)
  314.         return bh;
  315.     ll_rw_block (READ, 1, &bh);
  316.     wait_on_buffer (bh);
  317.     if (bh->b_uptodate)
  318.         return bh;
  319.     brelse (bh);
  320.     *err = -EIO;
  321.     return NULL;
  322. }
  323.  
  324. void ext2_read_inode (struct inode * inode)
  325. {
  326.     struct buffer_head * bh;
  327.     struct ext2_inode * raw_inode;
  328.     unsigned long block_group;
  329.     unsigned long group_desc;
  330.     unsigned long desc;
  331.     unsigned long block;
  332.     struct ext2_group_desc * gdp;
  333.  
  334.     if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
  335.          inode->i_ino != EXT2_ACL_DATA_INO && inode->i_ino < EXT2_FIRST_INO) ||
  336.         inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
  337.         ext2_error (inode->i_sb, "ext2_read_inode",
  338.                 "bad inode number: %lu", inode->i_ino);
  339.         return;
  340.     }
  341.     block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
  342.     if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
  343.         ext2_panic (inode->i_sb, "ext2_read_inode",
  344.                 "group >= groups count");
  345.     group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
  346.     desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
  347.     bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
  348.     if (!bh)
  349.         ext2_panic (inode->i_sb, "ext2_read_inode",
  350.                 "Descriptor not loaded");
  351.     gdp = (struct ext2_group_desc *) bh->b_data;
  352.     block = gdp[desc].bg_inode_table +
  353.         (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
  354.          / EXT2_INODES_PER_BLOCK(inode->i_sb));
  355.     if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
  356.         ext2_panic (inode->i_sb, "ext2_read_inode",
  357.                 "unable to read i-node block\n"
  358.                 "inode=%lu, block=%lu", inode->i_ino, block);
  359.     raw_inode = ((struct ext2_inode *) bh->b_data) +
  360.         (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
  361.     inode->i_mode = raw_inode->i_mode;
  362.     inode->i_uid = raw_inode->i_uid;
  363.     inode->i_gid = raw_inode->i_gid;
  364.     inode->i_nlink = raw_inode->i_links_count;
  365.     inode->i_size = raw_inode->i_size;
  366.     inode->i_atime = raw_inode->i_atime;
  367.     inode->i_ctime = raw_inode->i_ctime;
  368.     inode->i_mtime = raw_inode->i_mtime;
  369.     inode->u.ext2_i.i_dtime = raw_inode->i_dtime;
  370.     inode->i_blksize = inode->i_sb->s_blocksize;
  371.     inode->i_blocks = raw_inode->i_blocks;
  372.     inode->u.ext2_i.i_flags = raw_inode->i_flags;
  373.     inode->u.ext2_i.i_faddr = raw_inode->i_faddr;
  374.     inode->u.ext2_i.i_frag = raw_inode->i_frag;
  375.     inode->u.ext2_i.i_fsize = raw_inode->i_fsize;
  376.     inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;
  377.     inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;
  378.     inode->u.ext2_i.i_version = raw_inode->i_version;
  379.     inode->u.ext2_i.i_block_group = block_group;
  380.     inode->u.ext2_i.i_next_alloc_block = 0;
  381.     inode->u.ext2_i.i_next_alloc_goal = 0;
  382.     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  383.         inode->i_rdev = raw_inode->i_block[0];
  384.     else for (block = 0; block < EXT2_N_BLOCKS; block++)
  385.         inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
  386.     brelse (bh);
  387.     inode->i_op = NULL;
  388.     if (inode->i_ino == EXT2_ACL_IDX_INO ||
  389.         inode->i_ino == EXT2_ACL_DATA_INO)
  390.         /* Nothing to do */ ;
  391.     else if (S_ISREG(inode->i_mode))
  392.         inode->i_op = &ext2_file_inode_operations;
  393.     else if (S_ISDIR(inode->i_mode))
  394.         inode->i_op = &ext2_dir_inode_operations;
  395.     else if (S_ISLNK(inode->i_mode))
  396.         inode->i_op = &ext2_symlink_inode_operations;
  397.     else if (S_ISCHR(inode->i_mode))
  398.         inode->i_op = &chrdev_inode_operations;
  399.     else if (S_ISBLK(inode->i_mode))
  400.         inode->i_op = &blkdev_inode_operations;
  401.     else if (S_ISFIFO(inode->i_mode))
  402.         init_fifo(inode);
  403.     if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
  404.         inode->i_flags |= MS_SYNC;
  405. }
  406.  
  407. static struct buffer_head * ext2_update_inode (struct inode * inode)
  408. {
  409.     struct buffer_head * bh;
  410.     struct ext2_inode * raw_inode;
  411.     unsigned long block_group;
  412.     unsigned long group_desc;
  413.     unsigned long desc;
  414.     unsigned long block;
  415.     struct ext2_group_desc * gdp;
  416.  
  417.     if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino < EXT2_FIRST_INO) ||
  418.         inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
  419.         ext2_error (inode->i_sb, "ext2_write_inode",
  420.                 "bad inode number: %lu", inode->i_ino);
  421.         return 0;
  422.     }
  423.     block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
  424.     if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
  425.         ext2_panic (inode->i_sb, "ext2_write_inode",
  426.                 "group >= groups count");
  427.     group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
  428.     desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
  429.     bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
  430.     if (!bh)
  431.         ext2_panic (inode->i_sb, "ext2_write_inode",
  432.                 "Descriptor not loaded");
  433.     gdp = (struct ext2_group_desc *) bh->b_data;
  434.     block = gdp[desc].bg_inode_table +
  435.         (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
  436.          / EXT2_INODES_PER_BLOCK(inode->i_sb));
  437.     if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
  438.         ext2_panic (inode->i_sb, "ext2_write_inode",
  439.                 "unable to read i-node block\n"
  440.                 "inode=%lu, block=%lu", inode->i_ino, block);
  441.     raw_inode = ((struct ext2_inode *)bh->b_data) +
  442.         (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
  443.     raw_inode->i_mode = inode->i_mode;
  444.     raw_inode->i_uid = inode->i_uid;
  445.     raw_inode->i_gid = inode->i_gid;
  446.     raw_inode->i_links_count = inode->i_nlink;
  447.     raw_inode->i_size = inode->i_size;
  448.     raw_inode->i_atime = inode->i_atime;
  449.     raw_inode->i_ctime = inode->i_ctime;
  450.     raw_inode->i_mtime = inode->i_mtime;
  451.     raw_inode->i_blocks = inode->i_blocks;
  452.     raw_inode->i_dtime = inode->u.ext2_i.i_dtime;
  453.     raw_inode->i_flags = inode->u.ext2_i.i_flags;
  454.     raw_inode->i_faddr = inode->u.ext2_i.i_faddr;
  455.     raw_inode->i_frag = inode->u.ext2_i.i_frag;
  456.     raw_inode->i_fsize = inode->u.ext2_i.i_fsize;
  457.     raw_inode->i_file_acl = inode->u.ext2_i.i_file_acl;
  458.     raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;
  459.     raw_inode->i_version = inode->u.ext2_i.i_version;
  460.     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  461.         raw_inode->i_block[0] = inode->i_rdev;
  462.     else for (block = 0; block < EXT2_N_BLOCKS; block++)
  463.         raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
  464.     bh->b_dirt = 1;
  465.     inode->i_dirt = 0;
  466.     return bh;
  467. }
  468.  
  469. void ext2_write_inode (struct inode * inode)
  470. {
  471.     struct buffer_head * bh;
  472.     bh = ext2_update_inode (inode);
  473.     brelse (bh);
  474. }
  475.  
  476. int ext2_sync_inode (struct inode *inode)
  477. {
  478.     int err = 0;
  479.     struct buffer_head *bh;
  480.  
  481.     bh = ext2_update_inode (inode);
  482.     if (bh && bh->b_dirt)
  483.     {
  484.         ll_rw_block (WRITE, 1, &bh);
  485.         wait_on_buffer (bh);
  486.         if (bh->b_req && !bh->b_uptodate)
  487.         {
  488.             printk ("IO error syncing ext2 inode [%04x:%08lx]\n",
  489.                 inode->i_dev, inode->i_ino);
  490.             err = -1;
  491.         }
  492.     }
  493.     else if (!bh)
  494.         err = -1;
  495.     brelse (bh);
  496.     return err;
  497. }
  498.